/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package com.inspur.edp.metadata.rtcustomization.construct.schedual;

import com.inspur.edp.lcm.metadata.configuration.CacheModeEnum;
import com.inspur.edp.lcm.metadata.configuration.CustomizationCacheHelper;
import com.inspur.edp.metadata.rtcustomization.common.LockUtils;
import com.inspur.edp.metadata.rtcustomization.common.TenantUtils;
import com.inspur.edp.metadata.rtcustomization.serverapi.CustomizationRtServerService;
import com.inspur.edp.metadata.rtcustomization.serverapi.CustomizationServerService;
import io.iec.edp.caf.boot.context.CAFContext;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import io.iec.edp.caf.tenancy.api.ITenantService;
import io.iec.edp.caf.tenancy.api.entity.Tenant;
import io.iec.edp.caf.tenancy.core.context.MultiTenantContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.UndeclaredThrowableException;
import java.util.List;

@Slf4j
public class MdpkgChangedRunnable implements Runnable {
    private static final String MDPKG_CHANGED_RUNNABLE_LOCK = "lcm-MdpkgChagedRunnable-run-lock";
    private static final CacheModeEnum cacheModeEnum = CustomizationCacheHelper.getInstance().getCacheMode();

    @Override
    public void run() {
        if (!LockUtils.tryLock(MDPKG_CHANGED_RUNNABLE_LOCK)) {
            return;
        }
        if (cacheModeEnum == CacheModeEnum.MULTI_TENANT) {
            multiTenantRun();
        } else {
            singleTenantRun();
        }
    }

    private void singleTenantRun() {
        CustomizationRtServerService rtServerService = SpringBeanUtils.getBean(CustomizationRtServerService.class);
        CustomizationServerService serverService = SpringBeanUtils.getBean(CustomizationServerService.class);

        try {
            rtServerService.afterMdpkgChanged(false);
        } catch (UndeclaredThrowableException e) {
            log.error("元数据部署后事件出现未声明的可抛出异常，请查看日志确认具体原因。", e);
        } catch (Exception e) {
            log.error("元数据部署后事件异常", e);
            if (cacheModeEnum == CacheModeEnum.MULTI_TENANT) {
                log.error("请检查tenantId:" + MultiTenantContextHolder.get().getTenantId() + "数据库。");
            }
        }

        try {
            serverService.afterMetadataChanged();
        } catch (Exception e) {
            log.error("运行时生成元数据变更异常", e);
        }
    }

    private void multiTenantRun() {
        ITenantService tenantService = SpringBeanUtils.getBean(ITenantService.class);
        List<Tenant> allTenants = tenantService.getAllTenants(CAFContext.current.getLanguage());
        if (CollectionUtils.isEmpty(allTenants)) {
            return;
        }

        for (Tenant tenant : allTenants) {
            // 在context中设置租户信息
            MultiTenantContextHolder.set(TenantUtils.buildTenantContext(tenant));
            // 单租户刷新
            singleTenantRun();
        }
    }
}